package org.budo.aliyun.sdk.impl;

import java.util.Map;

import org.budo.aliyun.sdk.util.BudoAliyunSdkUtil;
import org.budo.support.http.client.Request;
import org.budo.support.http.client.Response;
import org.budo.support.lang.util.MapUtil;
import org.budo.support.slf4j.Slf4j;
import org.budo.time.Time;
import org.slf4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * @author lmw
 */
public abstract class AbstractBudoAliyunSdk {
    private static final Logger log = Slf4j.getLogger();

    private static final String HMAC_SHA1 = "HMAC-SHA1";

    private static final String FORMAT_JSON = "json";

    private static final String SIGNATURE_VERSION_1 = "1.0";

    private String url;

    private String version;

    private String accessKeyId;

    private String accessKeySecret;

    protected Map<String, Object> commonParameters() {
        String signatureNonce = Math.random() + "";
        String timestamp = Time.now().minusHour(8).toString("yyyy-MM-dd'T'HH:mm:ss'Z'"); // UTC 时间

        Map<String, Object> parameters = MapUtil.stringObjectMap("Format", FORMAT_JSON, // 
                "Version", this.getVersion(), // 
                "SignatureMethod", HMAC_SHA1, // 
                "SignatureVersion", SIGNATURE_VERSION_1, // 
                "AccessKeyId", this.getAccessKeyId(),
                "Timestamp", timestamp,
                "SignatureNonce", signatureNonce);
        return parameters;
    }

    protected Response doRequest(Map<String, Object> parameters) {
        String signature = BudoAliyunSdkUtil.signature(parameters, this.getAccessKeySecret());
        signature = BudoAliyunSdkUtil.percentEncode(signature);
        parameters.put("Signature", signature); // 

        Request request = new Request();
        request.setUrl(this.getUrl());
        request.setParameters(parameters);
        Response response = request.execute();
        return response;
    }

    protected JSONObject responseJsonObject(Response response) {
        if (null == response || response.getStatus() != 200) {
            log.error("response is not 200, response=" + (null == response ? response : response.toSimpleString()));
            return new JSONObject();
        }

        String responseBody = response.getBody();
        if (null == responseBody || !responseBody.startsWith("{") || !responseBody.endsWith("}")) {
            log.error("response is not json, response=" + (null == response ? response : response.toSimpleString()));
        }

        return JSON.parseObject(responseBody);
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public void extendsProperties(AbstractBudoAliyunSdk sdk) {
        this.setAccessKeyId(sdk.getAccessKeyId());
        this.setAccessKeySecret(sdk.getAccessKeySecret());
    }
}